package org.hawk.gwt.ppc;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;

import org.hawk.gwt.ppc.javacc.ParseException;

/**
 * Simple wrapper for the debugger. You should pass the same arguments to this
 * entry point as you pass to the {@link CompilerWrapper}. In other case
 * debugger may fail on loading classes.
 * 
 * @author alex.bereznevatiy@gmail.com
 * 
 */
public class DevModeWrapper {
	private static final String GWT_DEV_MODE_CLASS_NAME = "com.google.gwt.dev.DevMode";
	private static boolean isDevMode;

	/**
	 * @param args
	 * @throws ParseException
	 * @throws IOException
	 * @throws FileNotFoundException
	 */
	public static void main(String[] args) throws ParseException, IOException {
		isDevMode = true;
		CmdArgs argsProcessor = new CmdArgs(args);
		Environment env = Environment.getInstance();
		env.configure(argsProcessor);
		try {
			main(env);
		} catch (NoClassDefFoundError e) {
			Log.error(
					"Unable to find GWT dev mode enty point class in the classpath",
					e);
			System.exit(1);
		} catch (ClassNotFoundException e) {
			Log.error(
					"Unable to find GWT dev mode enty point class in the classpath",
					e);
			System.exit(1);
		} catch (Throwable ex) {
			ex.printStackTrace();
			env.dispose();
			System.exit(1);
		}
	}

	private static void main(Environment env) throws IOException,
			ParseException, ClassNotFoundException, IllegalAccessException,
			InvocationTargetException, NoSuchMethodException {
		ClassLoader loader = CompilerWrapper.class.getClassLoader();
		try {
			ProcessingUnitsManager manager = ProcessingUnitsManager
					.getInstance();
			manager.run();
			loader = new ProcessedSourcesLoader(manager.getWorkLoader());
			Thread.currentThread().setContextClassLoader(loader);
		} catch (Throwable th) {
			Log.internalError(
					"GWT preprocessor encounter a fatal error. "
							+ "GWT dev mode enty point will try to run without preprocessing.\n",
					th);
		} finally {
			env.dispose();
		}
		gwtDevMode(env, loader);
	}

	private static void gwtDevMode(Environment env, ClassLoader loader)
			throws ClassNotFoundException, IllegalAccessException,
			InvocationTargetException, NoSuchMethodException {
		Class<?> cls = loader.loadClass(GWT_DEV_MODE_CLASS_NAME);
		cls.getMethod("main", String[].class).invoke(null,
				(Object) env.getCompillerArguments());
	}

	/**
	 * @return <code>true</code> if this launch represents {@link DevModeWrapper} launch and
	 *         <code>false</code> otherwise
	 */
	public static boolean isDevMode() {
		return isDevMode;
	}
}
